import re
import random

from flask import current_app, jsonify
from flask import request
from flask import session

from info import redis_store, db
from info.models import User
from info.utils.response_code import RET
from . import passport_blue
from info.utils.captcha.captcha import captcha
from info.constants import *
from flask import make_response


# 获取图片验证码
@passport_blue.route('/image_code')
def get_image_code():
    # 获取传过来的参数code_id
    code_id = request.args.get('code_id')
    # 调用captcha工具随机生成图片验证码
    name, text, image_code = captcha.generate_captcha()
    print(text)

    # 将Image_code_拼接code_id为键，text为值存储到redis中，过期时间是5分钟
    try:
        redis_store.set('Image_code_' + code_id, text, IMAGE_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库保存失败')

    # 返回中指定image_code是图片格式，避免有的浏览器不能解析
    response = make_response(image_code)
    response.headers['Content-Type'] = 'image/jpg'
    return response


# 获取短信验证码
@passport_blue.route('/sms_code', methods=['POST'])
def get_sms_code():
    # 获取参数
    params_dict = request.json
    mobile = params_dict.get('mobile')
    code_id = params_dict.get('image_code_id')
    image_code = params_dict.get('image_code')

    # 校验参数有效性，手机号
    if not all([mobile, code_id, image_code]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不齐')

    if not re.match(r'^1[3456789]\d{9}$', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号有误')

    # 逻辑处理
    # 1.1 查询redis中存储的图片验证码文本
    try:
        real_image_code = redis_store.get('Image_code_' + code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库查询错误')
    # 需要判断是否过期
    if not real_image_code:
        return jsonify(errno=RET.NODATA, errmsg='验证码已过期')

    # 获取到验证码的值之后可以及时删除，避免安全问题和资源浪费
    try:
        redis_store.delete('Image_code_' + code_id)
    except Exception as e:
        current_app.logger.error(e)

    # 1.2 比对传过来的验证码和数据库中的是否相符
    if real_image_code.upper() != image_code.upper():
        return jsonify(errno=RET.DATAERR, errmsg='验证码错误')

    # 2.1 对比成功，生成一个随机的6位短信码，配合手机号存到redis以及通过第三方发送给手机号
    sms_code = '%06d' % random.randint(1, 999999)

    # 查询mysql，是否已注册，没有才发送
    try:
        user = User.query.filter_by(mobile=mobile).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库查询错误')
    if user:
        return jsonify(errno=RET.DATAEXIST, errmsg='手机号已被注册')

    try:
        redis_store.set('Sms_code_' + mobile, sms_code, SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库写入错误')
    # TODO 调用第三方发送短信还没实现
    print(sms_code)

    # 返回
    return jsonify(errno=RET.OK, errmsg='发送成功')


# 点击注册
@passport_blue.route('/register', methods=['POST'])
def register():
    # 获取参数（电话，短信验证码，密码）
    params_dict = request.json
    mobile = params_dict.get('mobile')
    sms_code = params_dict.get('sms_code')
    password = params_dict.get('password')

    # 校验数据
    if not all([mobile, sms_code, password]):
        return jsonify(errno=RET.PARAMERR, errmsg='缺少参数')
    if not re.match(r'^1[3456789]\d{9}$', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号有误')

    # 查询redis中的数据是否相符
    try:
        real_sms_code = redis_store.get('Sms_code_' + mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库查询错误')
    if not real_sms_code:
        return jsonify(errno=RET.NODATA, errmsg='验证码过期')
    # 及时删除验证码
    try:
        redis_store.delete('Sms_code_' + mobile)
    except Exception as e:
        current_app.logger.error(e)

    if real_sms_code != sms_code:
        return jsonify(errno=RET.DATAERR, errmsg='验证码错误')

    # 查询mysql，是否已注册，没有才添加进去
    try:
        user = User.query.filter_by(mobile=mobile).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库查询错误')
    if user:
        return jsonify(errno=RET.DATAEXIST, errmsg='手机号已被注册')
    user = User()
    user.nick_name = mobile
    user.mobile = mobile
    # TODO 需要给密码加盐加密
    user.password = password
    db.session.add(user)
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库写入错误')

    # 注册成功后直接登录
    session['user_id'] = user.id
    session['nick_name'] = user.nick_name
    session['mobile'] = user.mobile

    # 返回ok
    return jsonify(errno=RET.OK, errmsg='注册成功')


# 登录
@passport_blue.route('/login', methods=['POST'])
def login():
    # 获取参数（手机号，密码）
    params_dict = request.json
    mobile = params_dict.get('mobile')
    password = params_dict.get('password')

    # 校验参数，有效性，手机号
    if not all([mobile, password]):
        return jsonify(errno=RET.PARAMERR, errmsg='缺少参数')
    if not re.match(r'1[3456789]\d{9}', mobile):
        return jsonify(errno=RET.DATAERR, errmsg='手机号格式错误')

    # 逻辑处理
    # 1.1 查询mysql数据库，是否已注册到数据库中，以及密码是否匹配
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库查询错误')
    if not user:
        return jsonify(errno=RET.NODATA, errmsg='账号不存在')
    # TODO 根据加盐加密获取密码
    if not user.check_password(password):
        return jsonify(errno=RET.DATAERR, errmsg='账号或密码错误')

    # 成功设置session实现状态保持
    session['user_id'] = user.id
    session['mobile'] = user.mobile
    session['nick_name'] = user.nick_name

    # 返回ok
    return jsonify(errno=RET.OK, errmsg='登录成功')
